package blms.system.user;

import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import blms.system.exception.restrictions.RestrictionException;
import blms.system.league.League;
import blms.system.util.BLMSMessages;
import blms.system.util.Validator;

/**
 * 
 */
public class User {

	private String email;
	private String firstName;
	private String lastName;
	private String homePhone;
	private String workPhone;
	private String cellPhone;
	private File picture;
	private Map<String, League> leagues;

	/**
	 * Creates a new User using the given parameters.
	 * 
	 * @param firstName
	 * @param lastName
	 * @param homePhone
	 * @param workPhone
	 * @param cellPhone
	 * @param email
	 * @param picture
	 */
	public User(String firstName, String lastName, String homePhone, String workPhone, String cellPhone, String email, File picture) {
		
		this.firstName = firstName;
		this.lastName = lastName;
		this.homePhone = homePhone;
		this.workPhone = workPhone;
		this.cellPhone = cellPhone;
		this.email = email;
		this.picture = picture;
		this.leagues = new HashMap<String, League>();
	}

	/**
	 * @return
	 */
	public String getFirstName() {
		return firstName;
	}
	
	/**
	 * @param firstName the firstName to set
	 * @throws RestrictionException 
	 */
	public void setFirstName(String firstName) throws RestrictionException {
		
		if (Validator.isBlankOrNull(firstName)) {
			throw new RestrictionException(BLMSMessages.REQUIRED_DATA_MESSAGE + "first name");
		}
		
		this.firstName = firstName;
	}

	/**
	 * @return
	 */
	public String getHomePhone() {
		return homePhone;
	}
	
	/**
	 * @param homePhone the homePhone to set
	 */
	public void setHomePhone(String homePhone) {
		
		if ( homePhone == null || homePhone.equals("") ) {
			if (!canEraseNumber()) {
				throw new IllegalArgumentException(BLMSMessages.NEED_AT_LEAST_ONE_PHONE_MESSAGE);
			}
		}
		
		this.homePhone = homePhone;
	}

	/**
	 * @return
	 */
	public String getWorkPhone() {
		return workPhone;
	}
	
	/**
	 * @param workPhone the workPhone to set
	 */
	public void setWorkPhone(String workPhone) {
		
		if ( workPhone == null || workPhone.equals("") ) {
			if (!canEraseNumber()) {
				throw new IllegalArgumentException(BLMSMessages.NEED_AT_LEAST_ONE_PHONE_MESSAGE);
			}
		}
		
		this.workPhone = workPhone;
	}

	/**
	 * @return
	 */
	public String getCellPhone() {
		return cellPhone;
	}
	
	/**
	 * @param cellPhone the cellPhone to set
	 */
	public void setCellPhone(String cellPhone) {
		
		if ( cellPhone == null || cellPhone.equals("") ) {
			if (!canEraseNumber()) {
				throw new IllegalArgumentException(BLMSMessages.NEED_AT_LEAST_ONE_PHONE_MESSAGE);
			}
		}
		
		this.cellPhone = cellPhone;
	}

	/**
	 * @return
	 */
	public File getPicture() {
		return picture;
	}
	
	/**
	 * @param picture the picture to set
	 */
	public void setPicture(File picture) {
		this.picture = picture;
	}

	/**
	 * Returns the email of this <code>User</code>. The email of a user is his identifier for the system.
	 * Calling this method has the same effect that calling getID() method.
	 * @return The email of this <code>User</code>.
	 */
	public String getEmail() {
		return this.email;
	}
	
	/**
	 * @param email the email to set
	 * @throws RestrictionException 
	 */
	public void setEmail(String email) throws RestrictionException {
		
		if (Validator.isBlankOrNull(email)) {
			throw new RestrictionException(BLMSMessages.REQUIRED_DATA_MESSAGE + "email");
		}
		
		this.email = email;
	}
	
	/**
	 * Returns the id of the user. Calling this method has the same effect that calling getID() method.
	 * 
	 * @return The id of the user.
	 */
	public String getID() {
		return this.getEmail();
	}

	private boolean canEraseNumber() {

		int count = 0;
		if (cellPhone != null && !cellPhone.equals("")) count++;
		if (homePhone != null && !homePhone.equals("")) count++;
		if (workPhone != null && !workPhone.equals("")) count++;
		
		if (count < 2) return false;
		return true;
	}

	/**
	 * Returns the last name of this <code>User</code>.
	 * @return the last name of this <code>User</code>.
	 */
	public String getLastName() {
		return this.lastName;
	}
	
	/**
	 * @param lastName the lastName to set
	 * @throws RestrictionException 
	 */
	public void setLastName(String lastName) throws RestrictionException {
		
		if (Validator.isBlankOrNull(lastName)) {
			throw new RestrictionException(BLMSMessages.REQUIRED_DATA_MESSAGE + "last name");
		}
		
		this.lastName = lastName;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {

		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((cellPhone == null) ? 0 : cellPhone.hashCode());
		result = prime * result + ((email == null) ? 0 : email.hashCode());
		result = prime * result
				+ ((firstName == null) ? 0 : firstName.hashCode());
		result = prime * result
				+ ((homePhone == null) ? 0 : homePhone.hashCode());
		result = prime * result
				+ ((lastName == null) ? 0 : lastName.hashCode());
		result = prime * result + ((picture == null) ? 0 : picture.hashCode());
		result = prime * result
				+ ((workPhone == null) ? 0 : workPhone.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {

		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final User other = (User) obj;
		if (cellPhone == null) {
			if (other.cellPhone != null)
				return false;
		} else if (!cellPhone.equals(other.cellPhone))
			return false;
		if (email == null) {
			if (other.email != null)
				return false;
		} else if (!email.equals(other.email))
			return false;
		if (firstName == null) {
			if (other.firstName != null)
				return false;
		} else if (!firstName.equals(other.firstName))
			return false;
		if (homePhone == null) {
			if (other.homePhone != null)
				return false;
		} else if (!homePhone.equals(other.homePhone))
			return false;
		if (lastName == null) {
			if (other.lastName != null)
				return false;
		} else if (!lastName.equals(other.lastName))
			return false;
		if (picture == null) {
			if (other.picture != null)
				return false;
		} else if (!picture.equals(other.picture))
			return false;
		if (workPhone == null) {
			if (other.workPhone != null)
				return false;
		} else if (!workPhone.equals(other.workPhone))
			return false;
		return true;
	}

	/**
	 * @return
	 */
	public Collection<League> getLeagues() {
		return this.leagues.values();
	}

	/**
	 * @param league
	 */
	public void addLeague(League league) {
		this.leagues.put(league.getId(), league);//TODO: O id da league nao seria suficiente
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return getID();
	}
}